package com.fenquen.dfs.base.protocol.data.storage_source.req_from_storage;

import com.alibaba.fastjson.annotation.JSONField;
import com.fenquen.dfs.base.protocol.Protocol;
import com.fenquen.dfs.base.protocol.data.storage_source.StorageSource;
import com.fenquen.dfs.base.utils.BiUtils;

import java.nio.ByteBuffer;
import java.util.Objects;

/**
 * 存储节点向路由节点上报的自身信息
 */
public class StorageNode extends ReqFromStorage implements Comparable<StorageNode> {
    /**
     * 4个字节，存储节点的ip地址
     */
    public String host;
    public static final int hostByteLength = 4;

    /**
     * 2个字节,存储节点接收上传文件的http的port
     */
    public Integer port;
    public static final int portByteLength = 2;

    /**
     * 该节点剩下的存储空间单位字节
     */
    public Long remainingSpaceByte;
    public static final int remainingSpaceByteByteLength = 8;

    /**
     * 该数据到达router的时间,不在协议种
     */
    public Long timestamp;


    @Override
    public StorageSource parseBinary(ByteBuffer byteBuffer) {
        byte[] temp = new byte[hostByteLength];
        byteBuffer.get(temp);
        host = BiUtils.bytes2Ip(temp);

        port = BiUtils.getUShort(byteBuffer.getShort());

        remainingSpaceByte = byteBuffer.getLong();

        return this;
    }

    @JSONField(serialize = false)
    @Override
    public int getByteLength() {
        return hostByteLength + portByteLength + remainingSpaceByteByteLength;
    }

    @JSONField(serialize = false)
    @Override
    public byte[] getByteArr() {
        ByteBuffer byteBuffer = ByteBuffer.allocate(getByteLength());

        byteBuffer.put(BiUtils.ip2ByteArr(host));
        byteBuffer.putShort((short) (port & 0xffff));
        byteBuffer.putLong(remainingSpaceByte);

        return byteBuffer.array();
    }

    @Override
    public Byte getProtocolType() {
        return Protocol.ProtocolType.ReqFromStorage.存储节点自身状态信息;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        StorageNode that = (StorageNode) o;
        return host.equals(that.host) &&
                port.equals(that.port);
    }

    @Override
    public int hashCode() {
        return Objects.hash(host, port);
    }

    @Override
    public int compareTo(StorageNode o) {
        // 实现倒序从大到小排列
        if (remainingSpaceByte >= o.remainingSpaceByte) {
            return -1;
        }
        return 1;
    }

    @JSONField(serialize = false)
    public String getAddr() {
        return host + ":" + port;
    }
}
